package com.zjsru.leetcode75.level1;

/**
 * @Author: cookLee
 * @Date: 2023-11-22
 * 或运算的最小翻转次数
 * 你可以对 a 和 b 的二进制表示进行位翻转操作，返回能够使按位或运算   a OR b == c  成立的最小翻转次数。
 * 「位翻转操作」是指将一个数的二进制表示任何单个位上的 1 变成 0 或者 0 变成 1 。
 */
public class MinFlips {
    /**
     * 主
     * \
     * 输入：a = 2, b = 6, c = 5
     * 输出：3
     * 解释：翻转后 a = 1 , b = 4 , c = 5 使得 a OR b == c
     * \
     * 输入：a = 4, b = 2, c = 7
     * 输出：1
     * \
     * @param args args
     */
    public static void main(String[] args) {
        MinFlips minFlips = new MinFlips();
        int a = 2;
        int b = 6;
        int c = 5;
        System.out.println(minFlips.minFlips(a, b, c));
    }


    /**
     * 最小翻转
     *
     * @param a a
     * @param b b
     * @param c
     * @return int
     */
    public int minFlips(int a, int b, int c) {
        int ans = 0;
        //对于十进制整数 x，我们可以用 (x >> k) & 1 得到 x 二进制表示的第 k 位（最低位为第 0 位）。如果 x 二进制表示的位数小于 k，那么该表达式的值为零：
        for (int i = 0; i < 31; i++) {
            //获取各位数上的值
            int aBit = (a >> i) & 1;
            int bBit = (b >> i) & 1;
            int cBit = (c >> i) & 1;
            if (cBit == 0) {
                //若 cBit 的值为 0，那么 aBit 和 bBit 必须都为 0，需要的翻转次数为 aBit + bBit；
                ans += aBit + bBit;
            } else {
                // aBit 和 bBit 中至少有一个为 1，只有当它们都为 0 时，才需要 1 次翻转；
                if( bBit + aBit == 0){
                    ans ++;
                }
            }
        }
        return ans;
    }

}
